﻿// windows.h 中包含winsock2.h, 添加该宏可以避免重复包含winsock2.h
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <ctime>
#include <fstream>
#include <iostream>
#include <queue>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
#include <winsock2.h>

#include "netserver.h"
#include "str_format.h"

using namespace std;

int nets::NetServer::create_socket(int port) {
    int socket_ = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (socket_ == INVALID_SOCKET) {
        // Handle error
        printf("Create Socket Error: %d, LastError: %d\n", socket_, WSAGetLastError());
        return SOCKET_ERROR;
    }

    SOCKADDR_IN addr;
    addr.sin_family      = AF_INET;
    addr.sin_port        = htons(port);
    addr.sin_addr.s_addr = INADDR_ANY; // Bind to all interfaces

    if (bind(socket_, (SOCKADDR *)&addr, sizeof(addr)) == SOCKET_ERROR) {
        // Handle error
        closesocket(socket_);
        return SOCKET_ERROR;
    }

    return socket_;
}

void nets::NetServer::get_listen(int socket_) {
    if (listen(socket_, SOMAXCONN) == SOCKET_ERROR) {
        // Handle error
        closesocket(socket_);
        return;
    }
    // Server is now listening for incoming connections
}

void nets::NetServer::accept_connection(int socket_) {
    std::vector<std::thread> workers;
    for (int i = 0; i < 4; i++) {
        workers.emplace_back(thread(&NetServer::worker, this));
    }

    while (true) {
        SOCKADDR_IN client_addr;
        int         addr_len      = sizeof(client_addr);
        SOCKET      client_socket = accept(socket_, (SOCKADDR *)&client_addr, &addr_len);
        if (client_socket == INVALID_SOCKET) {
            // Handle error
            closesocket(client_socket); // Close the client socket when done
            continue;
        }
        // Successfully accepted a connection
        // Here you can handle the client socket, e.g., read/write data
        {
            lock_guard<mutex> lock(mtx);
            clients.push(client_socket);
        }
        cv.notify_one();
    }

    for (auto &t : workers) {
        t.join();
    }
}

void nets::NetServer::receive(int socket_) {
    char buffer[1024];
    int  bytes_received = recv(socket_, buffer, sizeof(buffer), 0);
    if (bytes_received > 0) {
        // TODO 可能超出1024字符
        // 添加字符串终止符
        buffer[bytes_received] = '\0';
        // Process received data
        printf("Received %d bytes: \n%.*s\n", bytes_received, bytes_received, buffer);

        // 获取当前时间
        time_t now;
        time(&now);
        char *time_char                  = ctime(&now);
        time_char[strlen(time_char) - 1] = 0;
        // 发送响应
        string      html              = "<b>my socket test http</b>";
        string      response_formated = str_format(this->STATUS_200.c_str(), time_char, html.size(), html.c_str());
        const char *response_body     = response_formated.c_str();

        response(socket_, response_body);
    } else if (bytes_received == 0) {
        // Connection closed
        close_socket(socket_);
    } else {
        // Handle error
        MessageBoxW(NULL, L"异常", L"Socket 接收异常", NULL);
    }
}

void nets::NetServer::response(int socket_, const char *response) {
    send(socket_, response, strlen(response), 0);
}

void nets::NetServer::worker() {
    while (true) {
        int socket_;
        {
            // 获取锁
            unique_lock<mutex> lock(mtx);
            // 等待条件变量通知
            cv.wait(lock, [this] { return !this->clients.empty(); });
            socket_ = this->clients.front();
            clients.pop();
        }
        this->receive(socket_);
    }
}

void nets::NetServer::close_socket(int socket_) {
    closesocket(socket_);
    WSACleanup();
}

void nets::NetServer::load_template() {
    stringstream ss;

    fstream file("conf\\200.template");
    if (file.is_open()) {
        string line;
        // 逐行读取文件内容
        while (getline(file, line)) {
            ss << line << endl;
        }

        file.close();

        this->STATUS_200 = ss.str();
    }
}